﻿#ifndef DM_BITS_H_
#define DM_BITS_H_

#include <dm/export.hpp>

#ifndef DM_API_MISC
#define DM_API_MISC DM_API_IMPORT
#endif

#include <dm/types.hpp>

namespace dm{

DM_API_MISC extern const uint8 SetBits8[8];
DM_API_MISC extern const uint8 ClrBits8[8];

DM_API_MISC extern const uint16 SetBits16[16];
DM_API_MISC extern const uint16 ClrBits16[16];


DM_API_MISC extern const uint32 SetBits32[32];
DM_API_MISC extern const uint32 ClrBits32[32];

#ifndef __TMS320C28XX__

DM_API_MISC extern const uint64 SetBits64[64];
DM_API_MISC extern const uint64 ClrBits64[64];
#endif

template<typename T>
inline bool bit_get(T w,const int& bit,const T* setArray ){
	return 0!=(w&setArray[bit]);
}

template<typename T>
inline T bit_set( T w,const int& bit,const T* setArray ){
	return w|setArray[bit];
}

template<typename T>
inline T bit_clr( T w,const int& bit,const T* clrArray ){
	return w&clrArray[bit];
}

inline bool bit_get( uint8 w,int bit ){
	return bit_get(w,bit,SetBits8);
}

inline uint8 bit_set( uint8 w,int bit ){
	return bit_set(w,bit,SetBits8);
}

inline uint8 bit_clr( uint8 w,int bit ){
	return bit_clr(w,bit,ClrBits8);
}

inline bool bit_get( uint16 w,int bit ){
	return bit_get(w,bit,SetBits16);
}

inline uint16 bit_set( uint16 w,int bit ){
	return bit_set(w,bit,SetBits16);
}

inline uint16 bit_clr( uint16 w,int bit ){
	return bit_clr(w,bit,ClrBits16);
}

#ifndef __TMS320C28XX__

inline bool bit_get( uint32 w,int bit ){
	return bit_get(w,bit,SetBits32);
}

inline uint32 bit_set( uint32 w,int bit ){
	return bit_set(w,bit,SetBits32);
}

inline uint32 bit_clr( uint32 w,int bit ){
	return bit_clr(w,bit,ClrBits32);
}

inline bool bit_get( uint64 w,int bit ){
	return bit_get(w,bit,SetBits64);
}

inline uint64 bit_set( uint64 w,int bit ){
	return bit_set(w,bit,SetBits64);
}

inline uint64 bit_clr( uint64 w,int bit ){
	return bit_clr(w,bit,ClrBits64);
}
#endif

template<typename T>
inline T bits_bytes( const T& bit ){
	return bit/8;
}

template<typename T>
inline T bits_offset( const T& bit ){
	return bit%8;
}

/**
 * 设置位串中的指定位
 * @param bit
 * @param data
 * @return
 */
template<typename T>
inline void bits_set(const T& bit,uint8* data ){
	T b = bits_bytes(bit);
	data[b] = bit_set(data[b],bits_offset(bit));
}

/**
 * 清除位串中的指定位
 * @param bit
 * @param data
 */
template<typename T>
inline void bits_clear( const T& bit,uint8* data ){
	T b = bits_bytes(bit);
	data[b] = bit_clr(data[b],bits_offset(bit));
}

/**
 * 获取位串中的指定位
 * @param bit
 * @param data
 * @return
 */
template<typename T>
inline bool bits_get( const T& bit,const uint8* data ){
	return bit_get(data[bits_bytes(bit)],bits_offset(bit));
}

/**
 * 获取左对齐位串中的指定位
 * @param bit
 * @param data
 */
template<typename T>
inline bool bits_get_l( const T& bit,const uint8* data ){
	return bit_get(data[bits_bytes(bit)],7-bits_offset(bit));
}

template<typename T>
inline void bits_set_l(const T& bit,uint8* data ){
	T b = bits_bytes(bit);
	data[b] = bit_set(data[b],7-bits_offset(bit));
}

template<typename T>
inline void bits_clear_l( const T& bit,uint8* data ){
	T b = bits_bytes(bit);
	data[b] = bit_clr(data[b],7-bits_offset(bit));
}

}

#endif /* COMMON_DATATYPES_BITS_H_ */
